﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Pointandclick.ScreenManagement
{
    class ScreenManager
    {

        #region Properties

        BaseScreen currentScreen, nextScreen, popUp;
        Game1 game;
        ContentManager content;
        float transitioning, speed;

        /// <summary>
        /// The Content manager used by all screens
        /// </summary>
        public ContentManager Content
        {
            get { return content; }
        }

        /// <summary>
        /// SpriteBatch used to draw the game
        /// </summary>
        public SpriteBatch SpriteBatch
        {
            get { return game.spriteBatch; }
        }

        /// <summary>
        /// The game window
        /// </summary>
        public GameWindow Window
        {
            get { return game.Window; }
        }

        #endregion

        /// <summary>
        /// the ScreenManager manages screens by updating and drawing the
        /// current screen and changing the current screen as necessary
        /// </summary>
        public ScreenManager(Game1 game)
        {
            this.game = game;
            content = game.Content;
            currentScreen = new MainMenuScreen(this);
            nextScreen = null;
            transitioning = 0;
            speed = 1f;
        }

        #region Helper Methods

        /// <summary>
        /// Transitioning to a new screen
        /// </summary>
        /// <param name="screen">New screen</param>
        public void ChangeScreen(BaseScreen screen)
        {
            nextScreen = screen;
        }

        /// <summary>
        /// Sets a pop up
        /// </summary>
        /// <param name="popUp">New popup</param>
        public void PopUp(BaseScreen popUp)
        {
            this.popUp = popUp;
        }

        /// <summary>
        /// Exits the game
        /// </summary>
        public void ExitGame()
        {
            game.Exit();
        }

        #endregion

        #region Update and Draw
        /// <summary>
        /// Updates the current Screen
        /// </summary>
        public void Update(GameTime gameTime)
        {
            Inputs.Update();
            if (currentScreen != null)
            {
                if (popUp != null)
                {
                    popUp.Update(gameTime);
                    transitioning = 0.5f;
                }
                else
                {
                    //This part of the code handles the transitioning
                    if (nextScreen != null)
                    {
                        //transitioning will go from 0 to 1 gradually
                        transitioning = (float)Math.Min(transitioning + speed * gameTime.ElapsedGameTime.TotalSeconds, 1.0);
                        if (transitioning == 1)
                        {
                            //when transitioning is complete, the currentScreen is switched with the new one
                            currentScreen = nextScreen;
                            nextScreen = null;
                        }
                    }
                    else
                    {
                        //The current screen will fade in
                        transitioning = (float)Math.Max(transitioning - speed * gameTime.ElapsedGameTime.TotalSeconds, 0);
                        currentScreen.Update(gameTime);
                    }
                }
            }
            //If there is no screen, then the game will exit
            else game.Exit();
        }

        /// <summary>
        /// Draws the current screen
        /// </summary>
        public void Draw()
        {
            if (currentScreen != null)
            {
                //Draws the currentScreen with the desired fading effect used to transition
                currentScreen.Draw(game.spriteBatch, new Color(1 - transitioning, 1 - transitioning, 1 - transitioning));
                if (popUp != null)
                {
                    popUp.Draw(game.spriteBatch, Color.White);
                }
            }
        }
        #endregion
    }
}
